package com.audaque.springboot.foshanupload.core.aspect;

/**
 * @author zgb
 * @desc ...
 * @date 2021-12-25 16:43:24
 */

import com.audaque.springboot.foshanupload.core.anno.GuauaLimiterAnno;
import com.audaque.springboot.foshanupload.core.component.GuauaRateLimiterProvider;
import com.google.common.util.concurrent.RateLimiter;
import lombok.Synchronized;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @Description : 非分布式限流
 **/
@Aspect
@Component
public class GuauaLimiterAnnoAspect {
    @Autowired
    GuauaRateLimiterProvider guauaRateLimiterProvider;

    @Around(value = "@annotation(com.audaque.springboot.foshanupload.core.anno.GuauaLimiterAnno)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {


        // 获取拦截的方法名
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();

        // 获取该方法的注解
        GuauaLimiterAnno guauaLimiterAnno = methodSignature.getMethod().getDeclaredAnnotation(GuauaLimiterAnno.class);

        //获取到注解的name,token
        String name = guauaLimiterAnno.name();
        double token = guauaLimiterAnno.token();
        String msg = guauaLimiterAnno.msg();

        RateLimiter rateLimiter = guauaRateLimiterProvider.getRateLimiter(name, token);

        //RateLimiter：先设置后获取，此处存在并发冲突，会报空指针异常
        if (!rateLimiter.tryAcquire()) {
            throw new Exception(msg);
        }

        return joinPoint.proceed();

    }


}

